#include "bitmap_index.h"
#include "index_manager.h"
#include "../memory/memory_manager.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>

static const uint32_t DEFAULT_HASH_TABLE_SIZE = 256;
static const uint32_t DEFAULT_INITIAL_CAPACITY = 1024;

static uint32_t bitmap_hash_default(const void* value, size_t value_size) {
    if (!value || value_size == 0) return 0;
    
    uint32_t hash = 2166136261u; // FNV-1a hash
    const uint8_t* bytes = (const uint8_t*)value;
    
    for (size_t i = 0; i < value_size; i++) {
        hash ^= bytes[i];
        hash *= 16777619u;
    }
    
    return hash;
}

static int bitmap_value_compare(const void* value1, size_t value1_size,
                               const void* value2, size_t value2_size) {
    if (!value1 && !value2) return 0;
    if (!value1) return -1;
    if (!value2) return 1;
    
    size_t min_size = value1_size < value2_size ? value1_size : value2_size;
    int result = memcmp(value1, value2, min_size);
    
    if (result == 0) {
        if (value1_size < value2_size) return -1;
        if (value1_size > value2_size) return 1;
        return 0;
    }
    
    return result;
}

bitmap_t* bitmap_create(memory_manager_t* memory_mgr, uint32_t initial_capacity) {
    if (!memory_mgr || initial_capacity == 0) return NULL;
    
    bitmap_t* bitmap = mm_alloc(memory_mgr, sizeof(bitmap_t), MEM_TYPE_INDEX_BUFFER);
    if (!bitmap) return NULL;
    
    memset(bitmap, 0, sizeof(bitmap_t));
    bitmap->memory_mgr = memory_mgr;
    
    uint32_t block_count = (initial_capacity + BITMAP_BLOCK_SIZE - 1) / BITMAP_BLOCK_SIZE;
    bitmap->block_count = block_count;
    bitmap->capacity_bits = block_count * BITMAP_BLOCK_SIZE;
    bitmap->set_bits = 0;
    
    bitmap->blocks = mm_alloc(memory_mgr, sizeof(bitmap_block_t) * block_count, 
                             MEM_TYPE_INDEX_BUFFER);
    if (!bitmap->blocks) {
        mm_free(memory_mgr, bitmap);
        return NULL;
    }
    
    memset(bitmap->blocks, 0, sizeof(bitmap_block_t) * block_count);
    
    return bitmap;
}

void bitmap_destroy(bitmap_t* bitmap) {
    if (!bitmap) return;
    
    if (bitmap->blocks) {
        mm_free(bitmap->memory_mgr, bitmap->blocks);
    }
    
    mm_free(bitmap->memory_mgr, bitmap);
}

index_result_t bitmap_set_bit(bitmap_t* bitmap, uint32_t bit_position) {
    if (!bitmap) return INDEX_ERROR_INVALID_PARAM;
    
    if (bit_position >= bitmap->capacity_bits) {
        index_result_t resize_result = bitmap_resize(bitmap, bit_position + BITMAP_BLOCK_SIZE);
        if (resize_result != INDEX_SUCCESS) {
            return resize_result;
        }
    }
    
    uint32_t block_index = bit_position / BITMAP_BLOCK_SIZE;
    uint32_t bit_offset = bit_position % BITMAP_BLOCK_SIZE;
    
    bitmap_block_t mask = 1ULL << bit_offset;
    
    if (!(bitmap->blocks[block_index] & mask)) {
        bitmap->blocks[block_index] |= mask;
        bitmap->set_bits++;
    }
    
    return INDEX_SUCCESS;
}

index_result_t bitmap_clear_bit(bitmap_t* bitmap, uint32_t bit_position) {
    if (!bitmap || bit_position >= bitmap->capacity_bits) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    uint32_t block_index = bit_position / BITMAP_BLOCK_SIZE;
    uint32_t bit_offset = bit_position % BITMAP_BLOCK_SIZE;
    
    bitmap_block_t mask = 1ULL << bit_offset;
    
    if (bitmap->blocks[block_index] & mask) {
        bitmap->blocks[block_index] &= ~mask;
        bitmap->set_bits--;
    }
    
    return INDEX_SUCCESS;
}

bool bitmap_get_bit(bitmap_t* bitmap, uint32_t bit_position) {
    if (!bitmap || bit_position >= bitmap->capacity_bits) {
        return false;
    }
    
    uint32_t block_index = bit_position / BITMAP_BLOCK_SIZE;
    uint32_t bit_offset = bit_position % BITMAP_BLOCK_SIZE;
    
    bitmap_block_t mask = 1ULL << bit_offset;
    return (bitmap->blocks[block_index] & mask) != 0;
}

index_result_t bitmap_resize(bitmap_t* bitmap, uint32_t new_capacity) {
    if (!bitmap || new_capacity <= bitmap->capacity_bits) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    uint32_t new_block_count = (new_capacity + BITMAP_BLOCK_SIZE - 1) / BITMAP_BLOCK_SIZE;
    bitmap_block_t* new_blocks = mm_alloc(bitmap->memory_mgr,
                                         sizeof(bitmap_block_t) * new_block_count,
                                         MEM_TYPE_INDEX_BUFFER);
    if (!new_blocks) {
        return INDEX_ERROR_OUT_OF_MEMORY;
    }
    
    memset(new_blocks, 0, sizeof(bitmap_block_t) * new_block_count);
    memcpy(new_blocks, bitmap->blocks, sizeof(bitmap_block_t) * bitmap->block_count);
    
    mm_free(bitmap->memory_mgr, bitmap->blocks);
    bitmap->blocks = new_blocks;
    bitmap->block_count = new_block_count;
    bitmap->capacity_bits = new_block_count * BITMAP_BLOCK_SIZE;
    
    return INDEX_SUCCESS;
}

uint32_t bitmap_count_set_bits(bitmap_t* bitmap) {
    if (!bitmap) return 0;
    return bitmap->set_bits;
}

uint32_t bitmap_find_first_set_bit(bitmap_t* bitmap, uint32_t start_position) {
    if (!bitmap || start_position >= bitmap->capacity_bits) {
        return UINT32_MAX;
    }
    
    uint32_t block_index = start_position / BITMAP_BLOCK_SIZE;
    uint32_t bit_offset = start_position % BITMAP_BLOCK_SIZE;
    
    for (uint32_t i = block_index; i < bitmap->block_count; i++) {
        bitmap_block_t block = bitmap->blocks[i];
        
        if (i == block_index) {
            block &= ~((1ULL << bit_offset) - 1);
        }
        
        if (block != 0) {
            uint32_t bit_pos = __builtin_ctzll(block);
            return i * BITMAP_BLOCK_SIZE + bit_pos;
        }
        
        bit_offset = 0;
    }
    
    return UINT32_MAX;
}

uint32_t bitmap_find_next_set_bit(bitmap_t* bitmap, uint32_t current_position) {
    return bitmap_find_first_set_bit(bitmap, current_position + 1);
}

uint32_t bitmap_hash_value(const void* value, size_t value_size) {
    return bitmap_hash_default(value, value_size);
}

bitmap_value_entry_t* bitmap_find_value_entry(bitmap_index_t* bitmap_idx,
                                             const void* value, size_t value_size) {
    if (!bitmap_idx || !value) return NULL;
    
    uint32_t hash = bitmap_hash_value(value, value_size);
    uint32_t bucket = hash % bitmap_idx->hash_table_size;
    
    bitmap_value_entry_t* entry = bitmap_idx->value_hash_table[bucket];
    while (entry) {
        if (entry->value_size == value_size &&
            bitmap_value_compare(entry->value, entry->value_size, value, value_size) == 0) {
            return entry;
        }
        entry = entry->hash_next;
    }
    
    return NULL;
}

bitmap_value_entry_t* bitmap_create_value_entry(bitmap_index_t* bitmap_idx,
                                               const void* value, size_t value_size) {
    if (!bitmap_idx || !value) return NULL;
    
    bitmap_value_entry_t* entry = mm_alloc(bitmap_idx->memory_mgr,
                                          sizeof(bitmap_value_entry_t),
                                          MEM_TYPE_INDEX_BUFFER);
    if (!entry) return NULL;
    
    memset(entry, 0, sizeof(bitmap_value_entry_t));
    
    entry->value = mm_alloc(bitmap_idx->memory_mgr, value_size, MEM_TYPE_INDEX_BUFFER);
    if (!entry->value) {
        mm_free(bitmap_idx->memory_mgr, entry);
        return NULL;
    }
    memcpy(entry->value, value, value_size);
    entry->value_size = value_size;
    
    entry->bitmap = bitmap_create(bitmap_idx->memory_mgr, bitmap_idx->capacity_records);
    if (!entry->bitmap) {
        mm_free(bitmap_idx->memory_mgr, entry->value);
        mm_free(bitmap_idx->memory_mgr, entry);
        return NULL;
    }
    
    entry->value_id = bitmap_idx->distinct_values;
    entry->count = 0;
    
    uint32_t hash = bitmap_hash_value(value, value_size);
    uint32_t bucket = hash % bitmap_idx->hash_table_size;
    entry->hash_next = bitmap_idx->value_hash_table[bucket];
    bitmap_idx->value_hash_table[bucket] = entry;
    
    bitmap_idx->distinct_values++;
    
    return entry;
}

void bitmap_destroy_value_entry(bitmap_value_entry_t* entry, memory_manager_t* memory_mgr) {
    if (!entry) return;
    
    if (entry->value) {
        mm_free(memory_mgr, entry->value);
    }
    if (entry->bitmap) {
        bitmap_destroy(entry->bitmap);
    }
    
    mm_free(memory_mgr, entry);
}

bitmap_index_t* bitmap_index_create(memory_manager_t* memory_mgr, uint32_t initial_capacity) {
    if (!memory_mgr) return NULL;
    if (initial_capacity == 0) initial_capacity = DEFAULT_INITIAL_CAPACITY;
    
    bitmap_index_t* bitmap_idx = mm_alloc(memory_mgr, sizeof(bitmap_index_t),
                                         MEM_TYPE_INDEX_BUFFER);
    if (!bitmap_idx) return NULL;
    
    memset(bitmap_idx, 0, sizeof(bitmap_index_t));
    bitmap_idx->memory_mgr = memory_mgr;
    bitmap_idx->hash_table_size = DEFAULT_HASH_TABLE_SIZE;
    bitmap_idx->max_cardinality = BITMAP_MAX_CARDINALITY;
    bitmap_idx->capacity_records = initial_capacity;
    bitmap_idx->allow_duplicates = true;
    bitmap_idx->auto_resize = true;
    
    bitmap_idx->value_hash_table = mm_alloc(memory_mgr,
                                           sizeof(bitmap_value_entry_t*) * bitmap_idx->hash_table_size,
                                           MEM_TYPE_INDEX_BUFFER);
    if (!bitmap_idx->value_hash_table) {
        mm_free(memory_mgr, bitmap_idx);
        return NULL;
    }
    memset(bitmap_idx->value_hash_table, 0,
           sizeof(bitmap_value_entry_t*) * bitmap_idx->hash_table_size);
    
    bitmap_idx->null_bitmap = bitmap_create(memory_mgr, initial_capacity);
    if (!bitmap_idx->null_bitmap) {
        mm_free(memory_mgr, bitmap_idx->value_hash_table);
        mm_free(memory_mgr, bitmap_idx);
        return NULL;
    }
    
    if (pthread_rwlock_init(&bitmap_idx->rwlock, NULL) != 0) {
        bitmap_destroy(bitmap_idx->null_bitmap);
        mm_free(memory_mgr, bitmap_idx->value_hash_table);
        mm_free(memory_mgr, bitmap_idx);
        return NULL;
    }
    
    return bitmap_idx;
}

void bitmap_index_destroy(bitmap_index_t* bitmap_idx) {
    if (!bitmap_idx) return;
    
    pthread_rwlock_wrlock(&bitmap_idx->rwlock);
    
    for (uint32_t i = 0; i < bitmap_idx->hash_table_size; i++) {
        bitmap_value_entry_t* entry = bitmap_idx->value_hash_table[i];
        while (entry) {
            bitmap_value_entry_t* next = entry->hash_next;
            bitmap_destroy_value_entry(entry, bitmap_idx->memory_mgr);
            entry = next;
        }
    }
    
    if (bitmap_idx->value_hash_table) {
        mm_free(bitmap_idx->memory_mgr, bitmap_idx->value_hash_table);
    }
    
    if (bitmap_idx->null_bitmap) {
        bitmap_destroy(bitmap_idx->null_bitmap);
    }
    
    pthread_rwlock_unlock(&bitmap_idx->rwlock);
    pthread_rwlock_destroy(&bitmap_idx->rwlock);
    
    mm_free(bitmap_idx->memory_mgr, bitmap_idx);
}

index_result_t bitmap_index_insert(bitmap_index_t* bitmap_idx, const void* key, size_t key_size,
                                  const void* value, size_t value_size) {
    if (!bitmap_idx || !key || key_size == 0) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    pthread_rwlock_wrlock(&bitmap_idx->rwlock);
    
    bitmap_idx->inserts++;
    
    uint32_t record_id = bitmap_idx->total_records;
    
    if (bitmap_idx->distinct_values >= bitmap_idx->max_cardinality) {
        pthread_rwlock_unlock(&bitmap_idx->rwlock);
        return INDEX_ERROR_INDEX_FULL;
    }
    
    if (record_id >= bitmap_idx->capacity_records) {
        if (bitmap_idx->auto_resize) {
            index_result_t resize_result = bitmap_index_resize(bitmap_idx,
                                                             bitmap_idx->capacity_records * 2);
            if (resize_result != INDEX_SUCCESS) {
                pthread_rwlock_unlock(&bitmap_idx->rwlock);
                return resize_result;
            }
        } else {
            pthread_rwlock_unlock(&bitmap_idx->rwlock);
            return INDEX_ERROR_INDEX_FULL;
        }
    }
    
    if (!value) {
        bitmap_set_bit(bitmap_idx->null_bitmap, record_id);
        bitmap_idx->null_count++;
    } else {
        bitmap_value_entry_t* entry = bitmap_find_value_entry(bitmap_idx, value, value_size);
        if (!entry) {
            entry = bitmap_create_value_entry(bitmap_idx, value, value_size);
            if (!entry) {
                pthread_rwlock_unlock(&bitmap_idx->rwlock);
                return INDEX_ERROR_OUT_OF_MEMORY;
            }
        }
        
        bitmap_set_bit(entry->bitmap, record_id);
        entry->count++;
    }
    
    bitmap_idx->total_records++;
    
    pthread_rwlock_unlock(&bitmap_idx->rwlock);
    return INDEX_SUCCESS;
}

index_result_t bitmap_index_search(bitmap_index_t* bitmap_idx, const void* key, size_t key_size,
                                  index_search_result_t* result) {
    if (!bitmap_idx || !key || key_size == 0 || !result) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    pthread_rwlock_rdlock(&bitmap_idx->rwlock);
    
    bitmap_idx->searches++;
    
    result->found = false;
    result->value = NULL;
    result->value_size = 0;
    result->record_id = 0;
    
    bitmap_value_entry_t* entry = bitmap_find_value_entry(bitmap_idx, key, key_size);
    if (entry && entry->count > 0) {
        uint32_t first_record = bitmap_find_first_set_bit(entry->bitmap, 0);
        if (first_record != UINT32_MAX) {
            result->found = true;
            result->value = entry->value;
            result->value_size = entry->value_size;
            result->record_id = first_record;
        }
    }
    
    pthread_rwlock_unlock(&bitmap_idx->rwlock);
    
    return result->found ? INDEX_SUCCESS : INDEX_ERROR_KEY_NOT_FOUND;
}

index_result_t bitmap_index_delete(bitmap_index_t* bitmap_idx, const void* key, size_t key_size) {
    if (!bitmap_idx || !key || key_size == 0) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    pthread_rwlock_wrlock(&bitmap_idx->rwlock);
    
    bitmap_idx->deletes++;
    
    bitmap_value_entry_t* entry = bitmap_find_value_entry(bitmap_idx, key, key_size);
    if (!entry || entry->count == 0) {
        pthread_rwlock_unlock(&bitmap_idx->rwlock);
        return INDEX_ERROR_KEY_NOT_FOUND;
    }
    
    uint32_t first_record = bitmap_find_first_set_bit(entry->bitmap, 0);
    if (first_record == UINT32_MAX) {
        pthread_rwlock_unlock(&bitmap_idx->rwlock);
        return INDEX_ERROR_KEY_NOT_FOUND;
    }
    
    bitmap_clear_bit(entry->bitmap, first_record);
    entry->count--;
    
    pthread_rwlock_unlock(&bitmap_idx->rwlock);
    return INDEX_SUCCESS;
}

index_result_t bitmap_index_update(bitmap_index_t* bitmap_idx, const void* key, size_t key_size,
                                  const void* value, size_t value_size) {
    index_result_t delete_result = bitmap_index_delete(bitmap_idx, key, key_size);
    if (delete_result != INDEX_SUCCESS) {
        return delete_result;
    }
    
    return bitmap_index_insert(bitmap_idx, key, key_size, value, value_size);
}

bitmap_iterator_t* bitmap_index_range_scan(bitmap_index_t* bitmap_idx,
                                          const void* start_key, size_t start_key_size,
                                          const void* end_key, size_t end_key_size,
                                          bool forward) {
    if (!bitmap_idx) return NULL;
    
    // Note: end_key parameters are kept for interface compatibility
    // but not used in bitmap index range scans
    (void)end_key;
    (void)end_key_size;
    
    bitmap_iterator_t* iter = mm_alloc(bitmap_idx->memory_mgr,
                                      sizeof(bitmap_iterator_t),
                                      MEM_TYPE_INDEX_BUFFER);
    if (!iter) return NULL;
    
    memset(iter, 0, sizeof(bitmap_iterator_t));
    iter->index = bitmap_idx;
    iter->forward = forward;
    iter->is_valid = false;
    iter->current_record = 0;
    iter->end_record = bitmap_idx->total_records;
    
    if (start_key && start_key_size > 0) {
        iter->filter_entry = bitmap_find_value_entry(bitmap_idx, start_key, start_key_size);
        if (iter->filter_entry && iter->filter_entry->count > 0) {
            iter->current_bitmap = iter->filter_entry->bitmap;
            iter->current_record = bitmap_find_first_set_bit(iter->current_bitmap, 0);
            iter->is_valid = (iter->current_record != UINT32_MAX);
        }
    } else {
        if (bitmap_idx->distinct_values > 0) {
            for (uint32_t i = 0; i < bitmap_idx->hash_table_size; i++) {
                if (bitmap_idx->value_hash_table[i] && bitmap_idx->value_hash_table[i]->count > 0) {
                    iter->current_value_entry = bitmap_idx->value_hash_table[i];
                    iter->current_bitmap = iter->current_value_entry->bitmap;
                    iter->current_record = bitmap_find_first_set_bit(iter->current_bitmap, 0);
                    iter->is_valid = (iter->current_record != UINT32_MAX);
                    break;
                }
            }
        }
    }
    
    return iter;
}

bool bitmap_iterator_valid(bitmap_iterator_t* iter) {
    return iter && iter->is_valid && iter->current_record < iter->end_record;
}

index_result_t bitmap_iterator_next(bitmap_iterator_t* iter) {
    if (!iter || !iter->is_valid) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    if (iter->current_bitmap) {
        iter->current_record = bitmap_find_next_set_bit(iter->current_bitmap, iter->current_record);
        
        if (iter->current_record == UINT32_MAX) {
            if (iter->filter_entry) {
                iter->is_valid = false;
            } else {
                iter->value_index++;
                bool found = false;
                for (uint32_t i = iter->value_index; i < iter->index->hash_table_size; i++) {
                    if (iter->index->value_hash_table[i] && iter->index->value_hash_table[i]->count > 0) {
                        iter->current_value_entry = iter->index->value_hash_table[i];
                        iter->current_bitmap = iter->current_value_entry->bitmap;
                        iter->current_record = bitmap_find_first_set_bit(iter->current_bitmap, 0);
                        if (iter->current_record != UINT32_MAX) {
                            found = true;
                            break;
                        }
                    }
                }
                if (!found) {
                    iter->is_valid = false;
                }
            }
        }
    } else {
        iter->is_valid = false;
    }
    
    return INDEX_SUCCESS;
}

index_result_t bitmap_iterator_current(bitmap_iterator_t* iter,
                                      void** key, size_t* key_size,
                                      void** value, size_t* value_size) {
    if (!iter || !iter->is_valid || !iter->current_value_entry) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    if (key) *key = iter->current_value_entry->value;
    if (key_size) *key_size = iter->current_value_entry->value_size;
    if (value) *value = iter->current_value_entry->value;
    if (value_size) *value_size = iter->current_value_entry->value_size;
    
    return INDEX_SUCCESS;
}

void bitmap_iterator_destroy(bitmap_iterator_t* iter) {
    if (!iter) return;
    
    mm_free(iter->index->memory_mgr, iter);
}

index_result_t bitmap_index_bulk_insert(bitmap_index_t* bitmap_idx,
                                       const void** keys, size_t* key_sizes,
                                       const void** values, size_t* value_sizes,
                                       size_t count) {
    if (!bitmap_idx || !keys || !key_sizes || count == 0) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    for (size_t i = 0; i < count; i++) {
        const void* value = values ? values[i] : NULL;
        size_t value_size = value_sizes ? value_sizes[i] : 0;
        
        index_result_t result = bitmap_index_insert(bitmap_idx, keys[i], key_sizes[i],
                                                   value, value_size);
        if (result != INDEX_SUCCESS && result != INDEX_ERROR_KEY_EXISTS) {
            return result;
        }
    }
    
    return INDEX_SUCCESS;
}

size_t bitmap_index_range_delete(bitmap_index_t* bitmap_idx,
                                const void* start_key, size_t start_key_size,
                                const void* end_key, size_t end_key_size) {
    if (!bitmap_idx) return 0;
    
    bitmap_iterator_t* iter = bitmap_index_range_scan(bitmap_idx,
                                                     start_key, start_key_size,
                                                     end_key, end_key_size, true);
    if (!iter) return 0;
    
    size_t deleted_count = 0;
    
    while (bitmap_iterator_valid(iter)) {
        void* key;
        size_t key_size;
        
        if (bitmap_iterator_current(iter, &key, &key_size, NULL, NULL) == INDEX_SUCCESS) {
            if (bitmap_index_delete(bitmap_idx, key, key_size) == INDEX_SUCCESS) {
                deleted_count++;
            }
        }
        
        bitmap_iterator_next(iter);
    }
    
    bitmap_iterator_destroy(iter);
    return deleted_count;
}

index_result_t bitmap_index_clear(bitmap_index_t* bitmap_idx) {
    if (!bitmap_idx) return INDEX_ERROR_INVALID_PARAM;
    
    pthread_rwlock_wrlock(&bitmap_idx->rwlock);
    
    for (uint32_t i = 0; i < bitmap_idx->hash_table_size; i++) {
        bitmap_value_entry_t* entry = bitmap_idx->value_hash_table[i];
        while (entry) {
            bitmap_value_entry_t* next = entry->hash_next;
            bitmap_destroy_value_entry(entry, bitmap_idx->memory_mgr);
            entry = next;
        }
        bitmap_idx->value_hash_table[i] = NULL;
    }
    
    bitmap_destroy(bitmap_idx->null_bitmap);
    bitmap_idx->null_bitmap = bitmap_create(bitmap_idx->memory_mgr, bitmap_idx->capacity_records);
    if (!bitmap_idx->null_bitmap) {
        pthread_rwlock_unlock(&bitmap_idx->rwlock);
        return INDEX_ERROR_OUT_OF_MEMORY;
    }
    
    bitmap_idx->distinct_values = 0;
    bitmap_idx->total_records = 0;
    bitmap_idx->null_count = 0;
    
    pthread_rwlock_unlock(&bitmap_idx->rwlock);
    return INDEX_SUCCESS;
}

index_result_t bitmap_index_rebuild(bitmap_index_t* bitmap_idx) {
    return bitmap_index_clear(bitmap_idx);
}

bool bitmap_index_validate(bitmap_index_t* bitmap_idx) {
    if (!bitmap_idx) return false;
    
    pthread_rwlock_rdlock(&bitmap_idx->rwlock);
    
    bool valid = (bitmap_idx->distinct_values <= bitmap_idx->max_cardinality) &&
                 (bitmap_idx->total_records <= bitmap_idx->capacity_records);
    
    pthread_rwlock_unlock(&bitmap_idx->rwlock);
    return valid;
}

void bitmap_index_get_stats(bitmap_index_t* bitmap_idx, index_stats_t* stats) {
    if (!bitmap_idx || !stats) return;
    
    pthread_rwlock_rdlock(&bitmap_idx->rwlock);
    
    memset(stats, 0, sizeof(index_stats_t));
    stats->total_keys = bitmap_idx->total_records;
    stats->searches = bitmap_idx->searches;
    stats->inserts = bitmap_idx->inserts;
    stats->deletes = bitmap_idx->deletes;
    stats->updates = bitmap_idx->updates;
    stats->range_scans = bitmap_idx->range_scans;
    stats->avg_chain_length = bitmap_idx->distinct_values > 0 ?
                             (double)bitmap_idx->total_records / bitmap_idx->distinct_values : 0.0;
    
    pthread_rwlock_unlock(&bitmap_idx->rwlock);
}

index_result_t bitmap_index_resize(bitmap_index_t* bitmap_idx, uint32_t new_capacity) {
    if (!bitmap_idx || new_capacity <= bitmap_idx->capacity_records) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    for (uint32_t i = 0; i < bitmap_idx->hash_table_size; i++) {
        bitmap_value_entry_t* entry = bitmap_idx->value_hash_table[i];
        while (entry) {
            index_result_t result = bitmap_resize(entry->bitmap, new_capacity);
            if (result != INDEX_SUCCESS) {
                return result;
            }
            entry = entry->hash_next;
        }
    }
    
    index_result_t result = bitmap_resize(bitmap_idx->null_bitmap, new_capacity);
    if (result != INDEX_SUCCESS) {
        return result;
    }
    
    bitmap_idx->capacity_records = new_capacity;
    return INDEX_SUCCESS;
}

double bitmap_index_get_selectivity(bitmap_index_t* bitmap_idx, const void* value, size_t value_size) {
    if (!bitmap_idx || !value || bitmap_idx->total_records == 0) {
        return 0.0;
    }
    
    bitmap_value_entry_t* entry = bitmap_find_value_entry(bitmap_idx, value, value_size);
    if (!entry) {
        return 0.0;
    }
    
    return (double)entry->count / bitmap_idx->total_records;
}

bool bitmap_should_use_bitmap_index(uint32_t total_records, uint32_t distinct_values) {
    if (total_records == 0 || distinct_values == 0) return false;
    
    double cardinality_ratio = (double)distinct_values / total_records;
    return cardinality_ratio < 0.1;
}

void bitmap_print(bitmap_t* bitmap) {
    if (!bitmap) return;
    
    printf("Bitmap: capacity=%u, set_bits=%u\n", bitmap->capacity_bits, bitmap->set_bits);
    for (uint32_t i = 0; i < bitmap->capacity_bits && i < 100; i++) {
        printf("%d", bitmap_get_bit(bitmap, i) ? 1 : 0);
        if ((i + 1) % 64 == 0) printf("\n");
    }
    printf("\n");
}

void bitmap_index_print_stats(bitmap_index_t* bitmap_idx) {
    if (!bitmap_idx) return;
    
    pthread_rwlock_rdlock(&bitmap_idx->rwlock);
    
    printf("Bitmap Index Statistics:\n");
    printf("  Total records: %u\n", bitmap_idx->total_records);
    printf("  Distinct values: %u\n", bitmap_idx->distinct_values);
    printf("  Capacity: %u\n", bitmap_idx->capacity_records);
    printf("  NULL count: %llu\n", (unsigned long long)bitmap_idx->null_count);
    printf("  Searches: %llu\n", (unsigned long long)bitmap_idx->searches);
    printf("  Inserts: %llu\n", (unsigned long long)bitmap_idx->inserts);
    printf("  Deletes: %llu\n", (unsigned long long)bitmap_idx->deletes);
    printf("  Cardinality ratio: %.3f\n",
           bitmap_idx->total_records > 0 ?
           (double)bitmap_idx->distinct_values / bitmap_idx->total_records : 0.0);
    
    pthread_rwlock_unlock(&bitmap_idx->rwlock);
}

static index_result_t bitmap_interface_insert(index_instance_t* index,
                                             const void* key, size_t key_size,
                                             const void* value, size_t value_size) {
    if (!index || !index->index_data) return INDEX_ERROR_INVALID_PARAM;
    bitmap_index_t* bitmap_idx = (bitmap_index_t*)index->index_data;
    return bitmap_index_insert(bitmap_idx, key, key_size, value, value_size);
}

static index_result_t bitmap_interface_delete(index_instance_t* index,
                                             const void* key, size_t key_size) {
    if (!index || !index->index_data) return INDEX_ERROR_INVALID_PARAM;
    bitmap_index_t* bitmap_idx = (bitmap_index_t*)index->index_data;
    return bitmap_index_delete(bitmap_idx, key, key_size);
}

static index_result_t bitmap_interface_update(index_instance_t* index,
                                             const void* key, size_t key_size,
                                             const void* value, size_t value_size) {
    if (!index || !index->index_data) return INDEX_ERROR_INVALID_PARAM;
    bitmap_index_t* bitmap_idx = (bitmap_index_t*)index->index_data;
    return bitmap_index_update(bitmap_idx, key, key_size, value, value_size);
}

static index_result_t bitmap_interface_search(index_instance_t* index,
                                             const void* key, size_t key_size,
                                             index_search_result_t* result) {
    if (!index || !index->index_data) return INDEX_ERROR_INVALID_PARAM;
    bitmap_index_t* bitmap_idx = (bitmap_index_t*)index->index_data;
    return bitmap_index_search(bitmap_idx, key, key_size, result);
}

static index_iterator_t* bitmap_interface_range_scan(index_instance_t* index,
                                                    const void* start_key, size_t start_key_size,
                                                    const void* end_key, size_t end_key_size,
                                                    bool forward) {
    if (!index || !index->index_data) return NULL;
    bitmap_index_t* bitmap_idx = (bitmap_index_t*)index->index_data;
    
    bitmap_iterator_t* bitmap_iter = bitmap_index_range_scan(bitmap_idx,
                                                           start_key, start_key_size,
                                                           end_key, end_key_size, forward);
    if (!bitmap_iter) return NULL;
    
    index_iterator_t* iter = mm_alloc(bitmap_idx->memory_mgr,
                                     sizeof(index_iterator_t),
                                     MEM_TYPE_INDEX_BUFFER);
    if (!iter) {
        bitmap_iterator_destroy(bitmap_iter);
        return NULL;
    }
    
    memset(iter, 0, sizeof(index_iterator_t));
    iter->index = index;
    iter->internal_state = bitmap_iter;
    iter->is_valid = bitmap_iterator_valid(bitmap_iter);
    iter->forward = forward;
    
    return iter;
}

static bool bitmap_interface_iterator_valid(index_iterator_t* iter) {
    if (!iter || !iter->internal_state) return false;
    bitmap_iterator_t* bitmap_iter = (bitmap_iterator_t*)iter->internal_state;
    return bitmap_iterator_valid(bitmap_iter);
}

static index_result_t bitmap_interface_iterator_next(index_iterator_t* iter) {
    if (!iter || !iter->internal_state) return INDEX_ERROR_INVALID_PARAM;
    bitmap_iterator_t* bitmap_iter = (bitmap_iterator_t*)iter->internal_state;
    return bitmap_iterator_next(bitmap_iter);
}

static index_result_t bitmap_interface_iterator_current(index_iterator_t* iter,
                                                       void** key, size_t* key_size,
                                                       void** value, size_t* value_size) {
    if (!iter || !iter->internal_state) return INDEX_ERROR_INVALID_PARAM;
    bitmap_iterator_t* bitmap_iter = (bitmap_iterator_t*)iter->internal_state;
    return bitmap_iterator_current(bitmap_iter, key, key_size, value, value_size);
}

static void bitmap_interface_iterator_destroy(index_iterator_t* iter) {
    if (!iter) return;
    
    if (iter->internal_state) {
        bitmap_iterator_t* bitmap_iter = (bitmap_iterator_t*)iter->internal_state;
        bitmap_iterator_destroy(bitmap_iter);
    }
    
    if (iter->index && iter->index->index_data) {
        bitmap_index_t* bitmap_idx = (bitmap_index_t*)iter->index->index_data;
        mm_free(bitmap_idx->memory_mgr, iter);
    }
}

static index_result_t bitmap_interface_bulk_insert(index_instance_t* index,
                                                  const void** keys, size_t* key_sizes,
                                                  const void** values, size_t* value_sizes,
                                                  size_t count) {
    if (!index || !index->index_data) return INDEX_ERROR_INVALID_PARAM;
    bitmap_index_t* bitmap_idx = (bitmap_index_t*)index->index_data;
    return bitmap_index_bulk_insert(bitmap_idx, keys, key_sizes, values, value_sizes, count);
}

static size_t bitmap_interface_range_delete(index_instance_t* index,
                                           const void* start_key, size_t start_key_size,
                                           const void* end_key, size_t end_key_size) {
    if (!index || !index->index_data) return 0;
    bitmap_index_t* bitmap_idx = (bitmap_index_t*)index->index_data;
    return bitmap_index_range_delete(bitmap_idx, start_key, start_key_size, end_key, end_key_size);
}

static index_result_t bitmap_interface_clear(index_instance_t* index) {
    if (!index || !index->index_data) return INDEX_ERROR_INVALID_PARAM;
    bitmap_index_t* bitmap_idx = (bitmap_index_t*)index->index_data;
    return bitmap_index_clear(bitmap_idx);
}

static index_result_t bitmap_interface_rebuild(index_instance_t* index) {
    if (!index || !index->index_data) return INDEX_ERROR_INVALID_PARAM;
    bitmap_index_t* bitmap_idx = (bitmap_index_t*)index->index_data;
    return bitmap_index_rebuild(bitmap_idx);
}

static void bitmap_interface_destroy(index_instance_t* index) {
    if (!index || !index->index_data) return;
    bitmap_index_t* bitmap_idx = (bitmap_index_t*)index->index_data;
    bitmap_index_destroy(bitmap_idx);
    index->index_data = NULL;
}

static void bitmap_interface_get_stats(index_instance_t* index, index_stats_t* stats) {
    if (!index || !index->index_data || !stats) return;
    bitmap_index_t* bitmap_idx = (bitmap_index_t*)index->index_data;
    bitmap_index_get_stats(bitmap_idx, stats);
}

static bool bitmap_interface_validate(index_instance_t* index) {
    if (!index || !index->index_data) return false;
    bitmap_index_t* bitmap_idx = (bitmap_index_t*)index->index_data;
    return bitmap_index_validate(bitmap_idx);
}

static index_result_t bitmap_interface_set_config(index_instance_t* index,
                                                 const index_config_t* config) {
    if (!index || !config) return INDEX_ERROR_INVALID_PARAM;
    
    memcpy(&index->config, config, sizeof(index_config_t));
    return INDEX_SUCCESS;
}

static void bitmap_interface_get_config(index_instance_t* index, index_config_t* config) {
    if (!index || !config) return;
    memcpy(config, &index->config, sizeof(index_config_t));
}

index_interface_t* bitmap_index_interface_create(void) {
    index_interface_t* interface = malloc(sizeof(index_interface_t));
    if (!interface) return NULL;
    
    memset(interface, 0, sizeof(index_interface_t));
    
    interface->insert = bitmap_interface_insert;
    interface->delete = bitmap_interface_delete;
    interface->update = bitmap_interface_update;
    interface->search = bitmap_interface_search;
    interface->range_scan = bitmap_interface_range_scan;
    interface->iterator_valid = bitmap_interface_iterator_valid;
    interface->iterator_next = bitmap_interface_iterator_next;
    interface->iterator_current = bitmap_interface_iterator_current;
    interface->iterator_destroy = bitmap_interface_iterator_destroy;
    interface->bulk_insert = bitmap_interface_bulk_insert;
    interface->range_delete = bitmap_interface_range_delete;
    interface->clear = bitmap_interface_clear;
    interface->rebuild = bitmap_interface_rebuild;
    interface->destroy = bitmap_interface_destroy;
    interface->get_stats = bitmap_interface_get_stats;
    interface->validate = bitmap_interface_validate;
    interface->set_config = bitmap_interface_set_config;
    interface->get_config = bitmap_interface_get_config;
    
    return interface;
}